package com.pccw.client.hessianclient;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import com.caucho.hessian.client.AbstractHessianConnection;
import com.caucho.hessian.client.HessianConnectionException;

public class MyHessionURLConnection extends AbstractHessianConnection {

	private URL url;
	private URLConnection conn;
	private ResponseHeadersParser parser;
	private int statusCode;
	private String statusMessage;

	public MyHessionURLConnection(URL url, URLConnection conn,ResponseHeadersParser parser) {
		this.url = url;
		this.conn = conn;
		this.parser=parser;
	}

	/**
	 * Adds a HTTP header.
	 */
	public void addHeader(String key, String value) {
		conn.setRequestProperty(key, value);
	}

	/**
	 * Returns the output stream for the request.
	 */
	public OutputStream getOutputStream() throws IOException {
		return conn.getOutputStream();
	}

	/**
	 * Sends the request
	 */
	public void sendRequest() throws IOException {
		if (conn instanceof HttpURLConnection) {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			statusCode = 500;
			try {
				statusCode = httpConn.getResponseCode();
			} catch (Exception e) {
			}
			parseResponseHeaders(httpConn);
			InputStream is = null;
			if (statusCode != 200) {
				StringBuffer sb = new StringBuffer();
				int ch;
				try {
					is = httpConn.getInputStream();
					if (is != null) {
						while ((ch = is.read()) >= 0)
							sb.append((char) ch);
						is.close();
					}
					is = httpConn.getErrorStream();
					if (is != null) {
						while ((ch = is.read()) >= 0)
							sb.append((char) ch);
					}
					statusMessage = sb.toString();
				} catch (FileNotFoundException e) {
					throw new HessianConnectionException(
							"HessianProxy cannot connect to '" + url, e);
				} catch (IOException e) {
					if (is == null)
						throw new HessianConnectionException(statusCode + ": "+ e, e);
					else
						throw new HessianConnectionException(statusCode + ": "+ sb, e);
				}
				if (is != null)
					is.close();
				throw new HessianConnectionException(statusCode + ": "+ sb.toString());
			}
		}
	}

	protected void parseResponseHeaders(HttpURLConnection conn) throws IOException {
		if(parser!=null){
			parser.parse(conn);
		}
	}

	/**
	 * Returns the status code.
	 */
	public int getStatusCode() {
		return statusCode;
	}

	/**
	 * Returns the status string.
	 */
	public String getStatusMessage() {
		return statusMessage;
	}

	/**
	 * Returns the InputStream to the result
	 */
	public InputStream getInputStream() throws IOException {
		return conn.getInputStream();
	}

	/**
	 * Close/free the connection
	 */
	public void close() {
	}

	/**
	 * Disconnect the connection
	 */
	public void destroy() {
		URLConnection connt = conn;
		conn = null;
		if (connt instanceof HttpURLConnection){
			((HttpURLConnection) connt).disconnect();
		}
	}
	
	public interface ResponseHeadersParser{
		void parse(HttpURLConnection conn) throws IOException ;
	}
}
